﻿using Bouyei.GeoCore.Converters;
using Bouyei.GeoCore.Geometries;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bouyei.GeoCore.GeoParsers.GeoPackage
{
    public class GeometryWriter
    {
        private Geometry geometry = null;
        private BitExtensions bitExt = null;
        private Wkb.GeometryWriter wkbWrite = null;

        public Ordinates Ordinates { get; set; } = Ordinates.XY;

        public GeometryWriter(Geometry geometry)
        {
            this.geometry = geometry;
            Ordinates = geometry.Ordinates;
            bitExt = new BitExtensions(ByteOrder.LittleEndian);
            wkbWrite = new Wkb.GeometryWriter(bitExt.ByteOrder);            
        }

        public byte[] Writer()
        {
            byte flag = (byte)(bitExt.ByteOrder + (getOrinates() << 1));
            var header = new GeoPackageHeader()
            {
                Extent = geometry.GetBoundrayBox(),
                Flags = flag,
                SRID = geometry.SRID,
            };
            var headerBytes = GeoPackageHeader.Write(header);

            using (MemoryStream ms = new MemoryStream())
            using (BinaryWriter binWriter = new BinaryWriter(ms))
            {
                binWriter.Write(headerBytes);
                var geoBytes = wkbWrite.Writer(geometry);
                binWriter.Write(geoBytes);

                return ms.ToArray();
            }
        }

        private int getOrinates()
        {
            int ordinates = 0;

            switch (Ordinates)
            {
                case Ordinates.None:
                    ordinates = 0;
                    break;
                case Ordinates.XY:
                    ordinates = 1;
                    break;
                case Ordinates.XYZ:
                    ordinates = 2;
                    break;
                case Ordinates.XYM:
                    ordinates = 3;
                    break;
                case Ordinates.XYZM:
                    ordinates = 4;
                    break;
            }
            return ordinates;
        }
    }
}
